% Variables
inputVideoName = 'video.mp4';
backgroundImageName = 'background_img.png';
smoothedVideoName = 'smoothed_video.mp4';
outputVideoName = 'new_video.mp4';
logFileName = 'log.csv';

foregroundThreshold = 32;

SMOOTH = true;
hSize = 5;
sigma = 2;

MASK = true;
maskNW = [1, 480];
maskSE = [360, 640];

CLOSE = true;
structuralElementSize = 18;

CONN_COMP = false;
minimumConnectedComponentSize = 50;

OVERLAY = true;
averagePersonSize = 8000;

SNAPSHOT = true;
frequency = 10;

LOG = true;
logFileID = fopen(strcat('../Videos/', logFileName), 'w');

% Reads the video
videoObj = readVideo(inputVideoName);

% Prints information about the video
printVideoInfo(videoObj);

if SMOOTH
    if ~(exist(strcat('../Videos/', smoothedVideoName), 'file') == 2)
        % Smooths the video and saves it on file
        smoothVideo(videoObj, smoothedVideoName, hSize, sigma);
    end
    % Reads the smoothed video from file
    videoObj = readVideo(smoothedVideoName);
end

if ~(exist(strcat('../Videos/', backgroundImageName), 'file') == 2)
    % Extracts the background image...
    backgroundImage = extractBackground(videoObj);
    % ... and prints it on file
    fprintf('\nPrinting the image on file...');
        imwrite(backgroundImage, strcat('../Videos/', backgroundImageName));
    fprintf('Done!\n');
end

% Reads the background image
fprintf('\nReading the incremental average image from file...');
    backgroundImage = imread(strcat('../Videos/', backgroundImageName));
fprintf('Done!\n');

% Generates the output video
fprintf('\nGenerating the video...');

outputVideoObj = VideoWriter(strcat('../Videos/', outputVideoName),'MPEG-4');
outputVideoObj.FrameRate = videoObj.FrameRate;
nFrames = videoObj.NumberOfFrames;

open(outputVideoObj);

if LOG
    fprintf(logFileID, 'f,\te,\tc\n');
end

for i = 1:nFrames
    
    frame = rgb2gray(read(videoObj, i));
    foregroundImage = extractForeground(frame, backgroundImage, foregroundThreshold);
     
    if MASK       
        % Applies a black mask
        foregroundImage = mask(foregroundImage, maskNW, maskSE);
    end
    
    if CLOSE
        % Performs morphological closing    
        structuralElement = ones(structuralElementSize, structuralElementSize);
        foregroundImage = imclose(foregroundImage, structuralElement);
    end
    
    if CONN_COMP
        % Removes connected components < minimumConnectedComponentSize
        foregroundImage = removeConnComp(foregroundImage, minimumConnectedComponentSize);
    end
    
    estimatedNumberOfPeople = estimate(foregroundImage, averagePersonSize);
    
    if OVERLAY
        foregroundImage = addOverlayText(foregroundImage, averagePersonSize);
    end
    
    if mod(i, frequency) == 0
        if SNAPSHOT
            imwrite(foregroundImage, strcat('../Videos/Snaps/', int2str(i), '.png'));

        end

        if LOG
            fprintf(logFileID, '%i,\t%i,\t\n', i, estimatedNumberOfPeople);
        end
    end
    
    writeVideo(outputVideoObj, foregroundImage);    
end
close(outputVideoObj);
fclose(logFileID);

fprintf('Done!\n');
